Listing B-1 Calculating the intertask signaling time
#include <Multiprocessing.h>
#include <Types.h>
#include <stdio.h>
#include <stdlib.h>
#include <sioux.h>
#include <math64.h>
#include <DriverServices.h>
enum {
aQueue = 0,
aSemaphore,
anEvent
} reflectOP;
MPOpaqueID waiterID, postID;
static OSStatus Reflector ( )
{
void*p1,*p2,*p3;
MPEventFlags events;
while (true)
{
switch (reflectOP)
{
case aQueue:
MPWaitOnQueue((MPQueueID) waiterID, &p1, &p2, &p3, kDurationForever);
break;
case aSemaphore:
MPWaitOnSemaphore((MPSemaphoreID) waiterID, kDurationForever);
break;
case anEvent:
MPWaitForEvent((MPEventID) waiterID, &events, kDurationForever);
break;
default:
return -123;
}
switch (reflectOP)
{
case aQueue:
MPNotifyQueue((MPQueueID) postID, &p1, &p2, &p3);
break;
case aSemaphore:
MPSignalSemaphore((MPSemaphoreID) postID);
break;
case anEvent:
MPSetEvent((MPEventID) postID, 0x01010101);
break;
default:
return -123;
}
}
return -123;
}
static float HowLong(
AbsoluteTime endTime,
AbsoluteTime bgnTime
)
{
AbsoluteTime absTime;
Nanoseconds nanosec;
absTime = SubAbsoluteFromAbsolute(endTime, bgnTime);
nanosec = AbsoluteToNanoseconds(absTime);
return (float) UnsignedWideToUInt64( nanosec ) / 1000.0;
}
void main ( void )
{
OSStatus err;
MPTaskID task;
UInt32 i, count;
void *p1,*p2,*p3;
MPEventFlags events;
AbsoluteTime nowTime, bgnTime;
float uSec;
char buff[10];
/* Set the console window defaults */
/* (this is a Metrowerks CodeWarrior thing). */
SIOUXSettings.autocloseonquit = true;
SIOUXSettings.asktosaveonclose = false;
SIOUXSettings.showstatusline = false;
SIOUXSettings.columns = 100;
SIOUXSettings.rows = 20;
SIOUXSettings.fontsize = 10;
// SIOUXSettings.fontid = monaco;
SIOUXSettings.standalone = true;
// DebugStr ( "\pStarting" );
/* Can't get very far without this one. */
if (!MPLibraryIsLoaded())
{
printf("The MP library did not load.\n");
return;
}
/* Find the overhead up UpTime. Perform a bunch of calls to average out */
/* cache effects. */
printf("\n");
bgnTime = UpTime();
for (i=0; i<16; i++)
{
nowTime = UpTime();
}
uSec = HowLong(nowTime, bgnTime);
uSec /= 16.0;
printf(" UpTime overhead: %.3f usec \n", uSec);
/* Time intertask communication. */
printf("\n Queues\n");
reflectOP = aQueue;
MPCreateQueue((MPQueueID*) &waiterID);
MPCreateQueue((MPQueueID*) &postID);
bgnTime = UpTime();
err = MPCreateTask( Reflector,
NULL,
0,
NULL,
0,
0,
kNilOptions,
&task );
nowTime = UpTime();
uSec = HowLong(nowTime, bgnTime);
printf(" MPCreateTask overhead: %.3f usec (may vary significantly) \n", uSec);
if (err != noErr)
{
printf(" Task not created!\n");
return;
}
count = 100000;
bgnTime = UpTime();
for (i=0; i<count; i++)
{
MPNotifyQueue((MPQueueID) waiterID, 0, 0, 0);
while (true)
{
err = MPWaitOnQueue((MPQueueID) postID, &p1, &p2, &p3, kDurationImmediate);
if (err != kMPTimeoutErr) break;
}
}
nowTime = UpTime();
uSec = HowLong(nowTime, bgnTime);
uSec /= ((float) count / 2.0); // Two trips.
printf(" Intertask signalling using queues overhead: %.3f usec \n", uSec);
/* Time intertask communication.
*/
MPTerminateTask(task, 123);
printf("\n Semaphores\n");
reflectOP = aSemaphore;
MPCreateSemaphore(1, 0, (MPSemaphoreID*) &waiterID);
MPCreateSemaphore(1, 0, (MPSemaphoreID*) &postID);
bgnTime = UpTime();
err = MPCreateTask( Reflector,
NULL,
0,
NULL,
0,
0,
kNilOptions,
&task );
nowTime = UpTime();
uSec = HowLong(nowTime, bgnTime);
printf(" MPCreateTask overhead: %.3f usec (may vary significantly) \n", uSec);
if (err != noErr)
{
printf(" Task not created!\n");
return;
}
count = 100000;
bgnTime = UpTime();
for (i=0; i<count; i++)
{
MPSignalSemaphore((MPSemaphoreID) waiterID);
while (true)
{
err = MPWaitOnSemaphore((MPSemaphoreID) postID, kDurationImmediate);
if (err != kMPTimeoutErr) break;
}
}
nowTime = UpTime();
uSec = HowLong(nowTime, bgnTime);
uSec /= ((float) count / 2.0);// Two trips.
printf(" Intertask signalling using sempahores overhead: %.3f usec \n", uSec);
/* Time intertask communication. */
MPTerminateTask(task, 123);
printf("\n Event Groups\n");
reflectOP = anEvent;
MPCreateEvent((MPEventID*) &waiterID);
MPCreateEvent((MPEventID*) &postID);
bgnTime = UpTime();
err = MPCreateTask( Reflector,
NULL,
0,
NULL,
0,
0,
kNilOptions,
&task );
nowTime = UpTime();
uSec = HowLong(nowTime, bgnTime);
printf(" MPCreateTask overhead: %.3f usec (may vary significantly) \n", uSec);
if (err != noErr)
{
printf(" Task not created!\n");
return;
}
count = 100000;
bgnTime = UpTime();
for (i=0; i<count; i++)
{
MPSetEvent((MPEventID) waiterID, 0x01);
while (true)
{
err = MPWaitForEvent((MPEventID) postID, &events, kDurationImmediate);
if (err != kMPTimeoutErr) break;
}
}
nowTime = UpTime();
uSec = HowLong(nowTime, bgnTime);
uSec /= ((float) count / 2.0);// Two trips.
printf(" Intertask signalling using events overhead: %.3f usec \n", uSec);
gets(buff);
}